package org.hamster.common.aggrid.model;

import java.util.Map;
import java.util.Set;

/**
 * Model representing the request from ag-Grid for infinite scrolling
 */
public class GetRowsRequest {
    private int startRow;
    private int endRow;
    private Map<String, SortModel> sortModel;
    private Map<String, FilterModel> filterModel;
    private Object context;

    public GetRowsRequest() {
    }

    public int getStartRow() {
        return startRow;
    }

    public void setStartRow(int startRow) {
        this.startRow = startRow;
    }

    public int getEndRow() {
        return endRow;
    }

    public void setEndRow(int endRow) {
        this.endRow = endRow;
    }

    public Map<String, SortModel> getSortModel() {
        return sortModel;
    }

    public void setSortModel(Map<String, SortModel> sortModel) {
        this.sortModel = sortModel;
    }

    public Map<String, FilterModel> getFilterModel() {
        return filterModel;
    }

    public void setFilterModel(Map<String, FilterModel> filterModel) {
        this.filterModel = filterModel;
    }

    public Object getContext() {
        return context;
    }

    public void setContext(Object context) {
        this.context = context;
    }

    /**
     * Validates that only allowed fields are accessed in sort and filter models
     * 
     * @param allowedFields Set of field names that are allowed to be sorted or filtered
     * @return true if all fields in sortModel and filterModel are in the allowedFields set, false otherwise
     */
    public boolean validateFields(Set<String> allowedFields) {
        // Validate sort model fields
        if (sortModel != null) {
            for (String field : sortModel.keySet()) {
                if (!allowedFields.contains(field)) {
                    return false;
                }
            }
        }
        
        // Validate filter model fields
        if (filterModel != null) {
            if (!validateFilterModelFields(filterModel, allowedFields)) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Recursively validates filter model fields including nested conditions
     * 
     * @param filterModelMap The filter model map to validate
     * @param allowedFields Set of allowed field names
     * @return true if all fields are allowed, false otherwise
     */
    private boolean validateFilterModelFields(Map<String, FilterModel> filterModelMap, Set<String> allowedFields) {
        for (Map.Entry<String, FilterModel> entry : filterModelMap.entrySet()) {
            String field = entry.getKey();
            FilterModel model = entry.getValue();
            
            // Check if field is allowed
            if (!allowedFields.contains(field)) {
                return false;
            }
            
            // Recursively validate conditions if they exist
            if (model.getConditions() != null && !model.getConditions().isEmpty()) {
                // For composite filters, we need to validate each condition
                for (FilterModel condition : model.getConditions()) {
                    // Conditions don't have their own field name, they apply to the parent field
                    // But they can also have nested conditions, so we need to validate recursively
                    if (condition.getConditions() != null && !condition.getConditions().isEmpty()) {
                        // Create a temporary map with the same field name for the nested condition
                        Map<String, FilterModel> nestedMap = Map.of(field, condition);
                        if (!validateFilterModelFields(nestedMap, allowedFields)) {
                            return false;
                        }
                    }
                }
            }
        }
        
        return true;
    }

    @Override
    public String toString() {
        return "GetRowsRequest{" +
                "startRow=" + startRow +
                ", endRow=" + endRow +
                ", sortModel=" + sortModel +
                ", filterModel=" + filterModel +
                ", context=" + context +
                '}';
    }
}